﻿using GWSoft.Framework.Core.Helpers;
using GWSoft.Framework.WebSite.IServices;
using GWSoft.Framework.WebSite.Models;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Cryptography;
using System.Text;

namespace GWSoft.Framework.WebSite.Controllers.Sys
{
    /// <summary>
    /// 用户账号控制类
    /// </summary>
    [Route("sys/accounts")]
    public class AccountController : Controller
    {
        private IAccountService iAccountService;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="accountService"></param>
        public AccountController(IAccountService accountService)
        {
            if (accountService == null)
                throw new ArgumentNullException(nameof(accountService));

            iAccountService = accountService;
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="loginInfo"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("login")]
        public IActionResult Login(string loginInfo)
        {
            string decryptLoginInfo = Decrypt(loginInfo, "f0f8ab4932884d54a5504fece6ef61ce");
            var anonymous = JsonConvert.DeserializeAnonymousType(decryptLoginInfo, new { loginName = string.Empty, loginPwd = string.Empty, loginTime = string.Empty, areaCode = string.Empty });
            var list = new List<Expression<Func<UserInfo, bool>>>();
            list.Add(c => c.LoginName == anonymous.loginName);
            list.Add(c => c.LoginPwd == anonymous.loginPwd);
            list.Add(c => c.AreaCode == anonymous.areaCode);
            Expression<Func<UserInfo, bool>> userInfoQueryTotal = null;
            foreach(var expression in list)
            {
                userInfoQueryTotal = expression.And(expression);
            }
            UserInfo userInfo = iAccountService.Get(where => where.LoginName == anonymous.loginName
                && where.LoginPwd == anonymous.loginPwd).FirstOrDefault();
            if(userInfo != null)
            {
                return Ok(userInfo);
            }
            return NotFound();
        }

        /// <summary>
        /// 获取加密串(测试)
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="loginPwd"></param>
        /// <param name="areaCode"></param>
        /// <param name="loginTime"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("encode")]
        public IActionResult Encode(string loginName, string loginPwd, string areaCode, string loginTime)
        {
            dynamic loginInfo = new { loginName = loginName, loginPwd = loginPwd, areaCode = areaCode, loginTime = loginTime };
            string loginInfoStr = JsonConvert.SerializeObject(loginInfo);
            return Ok(Encrypt(loginInfoStr, "f0f8ab4932884d54a5504fece6ef61ce"));
        }

        /// <summary>  
        /// AES加密  
        /// </summary>  
        /// <param name="encryptStr">明文</param>  
        /// <param name="key">密钥</param>  
        /// <returns></returns>  
        public static string Encrypt(string encryptStr, string key)
        {
            byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
            byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(encryptStr);
            RijndaelManaged rDel = new RijndaelManaged();
            rDel.Key = keyArray;
            rDel.Mode = CipherMode.ECB;
            rDel.Padding = PaddingMode.PKCS7;
            ICryptoTransform cTransform = rDel.CreateEncryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }

        /// <summary>  
        /// AES解密  
        /// </summary>  
        /// <param name="decryptStr">密文</param>  
        /// <param name="key">密钥</param>  
        /// <returns></returns>  
        public static string Decrypt(string decryptStr, string key)
        {
            byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
            byte[] toEncryptArray = Convert.FromBase64String(decryptStr);

            RijndaelManaged rDel = new RijndaelManaged();
            rDel.Key = keyArray;
            rDel.Mode = CipherMode.ECB;
            rDel.Padding = PaddingMode.PKCS7;

            ICryptoTransform cTransform = rDel.CreateDecryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return UTF8Encoding.UTF8.GetString(resultArray);
        }
    }
}
